﻿using System.Collections.Generic;

namespace ChivalryUnity.Fsm
{
    public abstract class State<T> where T : Fsm<T>
    {
        public delegate void HandleMessageCallback(string msg, object arg);

        private Dictionary<string, HandleMessageCallback> m_messageHandlers;

        /// <summary>
        /// 状态机
        /// </summary>
        public T Fsm { get; internal set; }

        /// <summary>
        /// 进入状态
        /// </summary>
        public void Enter()
        {
            OnEnter();
        }

        /// <summary>
        /// 离开状态
        /// </summary>
        public void Leave()
        {
            OnLeave();
        }

        /// <summary>
        /// 更新状态
        /// </summary>
        public void Update()
        {
            OnUpdate();
        }

        /// <summary>
        /// 注册消息
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="callback"></param>
        protected void RegisterMessage(string msg, HandleMessageCallback callback)
        {
            if (m_messageHandlers == null)
            {
                m_messageHandlers = new Dictionary<string, HandleMessageCallback>();
            }

            if (callback == null)
                return;

            if (m_messageHandlers.ContainsKey(msg))
            {
                m_messageHandlers[msg] += callback;
            }
            else
            {
                m_messageHandlers.Add(msg, callback);
            }
        }

        /// <summary>
        /// 注销消息
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="callback"></param>
        protected void UnregisterMessage(string msg, HandleMessageCallback callback)
        {
            if (m_messageHandlers == null)
                return;

            if (callback == null)
                return;

            if (m_messageHandlers.ContainsKey(msg))
            {
                m_messageHandlers[msg] -= callback;
                if (m_messageHandlers[msg] == null)
                {
                    m_messageHandlers.Remove(msg);
                }
            }
        }

        /// <summary>
        /// 处理消息
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="arg"></param>
        public void HandleMessage(string msg, object arg)
        {
            if (m_messageHandlers == null)
                return;

            HandleMessageCallback callback;
            m_messageHandlers.TryGetValue(msg, out callback);

            if (callback != null)
            {
                callback(msg, arg);
            }
        }

        protected virtual void OnEnter() { }
        protected virtual void OnLeave() { }
        protected virtual void OnUpdate() { }
    }
}